package com.tracking.application.fragments;


import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.followme.module.common.ReceiverManager;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.model.*;
import com.tracking.application.DataBase.DbAdapter;
import com.tracking.application.R;
import com.tracking.application.activities.TabsActivity;
import com.tracking.application.util.CommonModuleApp;

import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: Kamil.O
 * Description: Map tab activity
 * Date: 18.11.13
 * Time: 22:56
 */
public class MapFragment extends Fragment {
    MapView mapView;
    GoogleMap map;
    CameraPosition lastCameraPosition = null;
    private TabsActivity tabsActivity;

    private List<LatLng> archiveCoordinates = null;
    private long idRoad = -1;

    private DbAdapter db;

    private double lastFromGpsLattitude = -1;
    private double lastFromGpsLongtitude = -1;

    protected BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(CommonModuleApp.KEY_COORDINATES_TO_MAP)){
                Bundle bundle = intent.getExtras();
                double newLattitude = (Double) bundle.get(CommonModuleApp.KEY_GPS_LAT);
                double newLongtitude = (Double) bundle.get(CommonModuleApp.KEY_GPS_LONG);

                if (archiveCoordinates == null) archiveCoordinates = new ArrayList<LatLng>();
                archiveCoordinates.add(new LatLng(newLattitude, newLongtitude));

                drawLine(newLattitude, newLongtitude);
            }
        }
    };

    private void drawLine(double newLattitude, double newLongtitude) {
        double localLat, localLong;
        if (lastFromGpsLattitude == -1 && lastFromGpsLongtitude == -1){
            localLat = tabsActivity.getFirstLatitude();
            localLong = tabsActivity.getFirstLongitude();
        }else{
            localLat = lastFromGpsLattitude;
            localLong = lastFromGpsLongtitude;
        }

        if (tabsActivity.getLastMarker() != null){
            tabsActivity.getLastMarker().remove();
        }

        if (tabsActivity.getFirstMarker() != null){
            tabsActivity.getFirstMarker().remove();
        }

        map.addPolyline(new PolylineOptions().geodesic(true)
                .add(new LatLng(localLat, localLong))
                .add(new LatLng(newLattitude, newLongtitude)));

        LatLng currentLatLng = new LatLng(newLattitude, newLongtitude);
        CameraPosition myPosition = new CameraPosition.Builder().target(currentLatLng).zoom(17).tilt(30).build();
        map.animateCamera(CameraUpdateFactory.newCameraPosition(myPosition));

        tabsActivity.setLastMarker(
                map.addMarker(new MarkerOptions()
                .position(currentLatLng)
                .icon(BitmapDescriptorFactory.fromResource(R.drawable.gpsloc))
                .rotation(245))
        );


        this.lastFromGpsLattitude = newLattitude;
        this.lastFromGpsLongtitude = newLongtitude;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            tabsActivity = (TabsActivity) activity;
            db = new DbAdapter(tabsActivity);
            idRoad = tabsActivity.getIdRoad();

            if (!tabsActivity.isFromHistory()){
                ReceiverManager.registerBroadcatReceiver(tabsActivity, CommonModuleApp.KEY_COORDINATES_TO_MAP, broadcastReceiver);
            }
        } catch(ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement DataPullingInterface");
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.map_activity, container, false);
        mapView = (MapView) view.findViewById(R.id.map);
        mapView.onCreate(savedInstanceState);

        getCoordinatesFromDb(idRoad);
        initializeFragmentMap();
        if (tabsActivity.isFromHistory() || tabsActivity.getRedirectType().equals("SHOW_MAP")){
            drawRouteFromDb();
        }else if(tabsActivity.getRedirectType().equals("PLAY")){
            goToFirstPoint();
        }

        return view;
    }

    private void goToFirstPoint() {
        LatLng justOneCoordinates = new LatLng(tabsActivity.getFirstLatitude(), tabsActivity.getFirstLongitude());
        CameraPosition myPosition = new CameraPosition.Builder().target(justOneCoordinates).zoom(17).tilt(30).build();
        map.animateCamera(CameraUpdateFactory.newCameraPosition(myPosition));


        tabsActivity.setFirstMarker(
                map.addMarker(new MarkerOptions()
                .position(justOneCoordinates)
                .icon(BitmapDescriptorFactory.fromResource(R.drawable.gpsloc))
                .rotation(245)));

        db.open();
        db.insertLocation(tabsActivity.getFirstLatitude(), tabsActivity.getFirstLongitude(), this.idRoad, 0, 0, tabsActivity.getFirstAltitude());
        db.close();
    }

    private void getCoordinatesFromDb(long idRoadTemp) {
        db.open();
        archiveCoordinates = db.getAllLatLong(String.valueOf(idRoadTemp));
        db.close();
    }

    private void initializeFragmentMap() {
        map = mapView.getMap();
        map.setMapType(tabsActivity.getMapMode());

        try {
            MapsInitializer.initialize(this.getActivity());
        } catch (GooglePlayServicesNotAvailableException e) {
            e.printStackTrace();
        }
    }

    private void drawRouteFromDb() {
        if (tabsActivity.getFirstMarker() != null){
            tabsActivity.getFirstMarker().remove();
        }

        if (archiveCoordinates.size() >= 2){
            for (int i=1; i<archiveCoordinates.size(); i++){
                map.addPolyline(new PolylineOptions().geodesic(true)
                    .add(archiveCoordinates.get(i-1))
                    .add(archiveCoordinates.get(i)));
            }

            LatLng myLatLng = archiveCoordinates.get(archiveCoordinates.size() - 1);

            CameraPosition myPosition = new CameraPosition.Builder().target(myLatLng).zoom(17).tilt(30).build();
            map.animateCamera(CameraUpdateFactory.newCameraPosition(myPosition));

            map.addMarker(new MarkerOptions()
                    .position(myLatLng)
                    .icon(BitmapDescriptorFactory.fromResource(R.drawable.gpsloc))
                    .rotation(245));

        }else if(archiveCoordinates.size() == 1){
            LatLng justOneCoordinates = archiveCoordinates.get(0);
            CameraPosition myPosition = new CameraPosition.Builder().target(justOneCoordinates).zoom(17).tilt(30).build();
            map.animateCamera(CameraUpdateFactory.newCameraPosition(myPosition));
            map.addMarker(new MarkerOptions()
                    .position(justOneCoordinates)
                    .icon(BitmapDescriptorFactory.fromResource(R.drawable.gpsloc))
                    .rotation(245));
        }else{
            AlertDialog.Builder alertDialog = new AlertDialog.Builder(this.tabsActivity);
            alertDialog.setTitle(R.string.attention);
            alertDialog.setMessage(R.string.no_gps_coordinates);

            alertDialog.setNegativeButton(R.string.cancel_gps, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });

            alertDialog.show();
        }
    }

    @Override
    public void onStart() {
        super.onStart();
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        lastCameraPosition = map.getCameraPosition();
    }

    @Override
    public void onResume() {
        mapView.onResume();
        super.onResume();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
        ReceiverManager.unregisterReceiver(tabsActivity, broadcastReceiver);
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mapView.onLowMemory();
    }
}
